/* 
 * File:   Derivada_Lagrange.cpp
 * Author: jorgeorm
 * 
 * Created on 12 de enero de 2012, 10:33 PM
 */

#include <stdlib.h>

#include "Derivada_Lagrange.h"
#include "Lab7/Derivada_DifDivididas.h"


using namespace std;
Derivada_Lagrange::Derivada_Lagrange(long double xs[], int nDatos){
    errorLagrange=0;
    if(nDatos!=0){
        obj_polyLagrng.resetPolinomio();
//        Instancio lo sarrays
        this->ptr_arrayXs= new long double [nDatos];
        this->ptr_arrayYs= new long double [nDatos];
//        Los lleno
        for(int i=0;i<nDatos;i++){
            this->ptr_arrayXs[i]=xs[i];
        }
    }
    else cout<<"ERROOOR!!!!!!! ARRAY VACIO!!!!!!!1";
}


long double Derivada_Lagrange::getError()
{
    return this->errorLagrange;
}

long double Derivada_Lagrange::evaluarDerivada(long double x)
{
    long double output=0;
    
    output=obj_polyLagrng.evaluarPolinomio(x);
    
    this->errorLagrange= this->derivadaFuncion(x)-output;
        
    return output;
}

void Derivada_Lagrange::calcularDerivadaConLagrange(){
    this->calcularPolyLagrange();
//    cout<<"Polinomioantes de:";
//    this->obj_polyLagrng.imprimirPolinomio();
//    cout<<endl;
    this->obj_polyLagrng.derivadaPolinomio(obj_polyLagrng);
//    cout<<"Polinomio despues de:";
//    this->obj_polyLagrng.imprimirPolinomio();
//    cout<<endl;
    
}

void Derivada_Lagrange::calcularPolyLagrange(){
    Polinomio polyTmp1// Tendrá almacenado el polinomio resultante de la productoria, se utilizara como el temporal para la productoria
            ,polyTmp2/* Tendrá el polinomio creado a multiplicar*/
            ,polySumaParcial/*Se utiliza para almacenar la sumatoria*/;
    polySumaParcial.resetPolinomio();
    polySumaParcial.crearNodoPolinomio(0,0);
    int ajuste=0;
    ajuste=5;
    long double cte=0.0;
    for(int i=0;i<ajuste;i++)
    {
        polyTmp1.resetPolinomio();
        polyTmp1.crearNodoPolinomio(1.0,0);
        for(int j=0;j<ajuste;j++)
        {
            if(j==i)continue;
            else{
                polyTmp2.resetPolinomio();
                polyTmp2.crearNodoPolinomio(1.0,1);
                polyTmp2.crearNodoPolinomio(-1.0*ptr_arrayXs[j], 0);
                cte=1.0/(long double)(ptr_arrayXs[i]-ptr_arrayXs[j]);
                polyTmp2=polyTmp2.const_mult_poly(cte);
                polyTmp1=polyTmp1.PolinomioXPolinomio(polyTmp1,polyTmp2);
            }
        }
        polyTmp1.const_mult_poly(ptr_arrayYs[i]);
        //Sumo y_subi*L_subI
        //
        polySumaParcial=polySumaParcial.sumaPolinomio(polySumaParcial,polyTmp1);
    }
//    cout<<"Polinomioantes de:";
//    polySumaParcial.imprimirPolinomio();
//    cout<<endl;
    obj_polyLagrng.resetPolinomio();
    obj_polyLagrng=polySumaParcial;  
}

//Derivada_Lagrange::Derivada_Lagrange(const Derivada_Lagrange& orig) {
//}

Derivada_Lagrange::~Derivada_Lagrange() {
//    Destruyo
    free(ptr_arrayXs);
    free(ptr_arrayYs);
    this->obj_polyLagrng.~Polinomio();
    this->ptr_arrayXs=NULL;
    this->ptr_arrayYs=NULL;
    this->nDats=0;
}

